package com.library.servlet.admin;

import com.library.util.DBUtil;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONObject;
import org.json.JSONArray;
import com.google.gson.Gson;
import java.io.BufferedReader;
import java.util.UUID;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.io.UnsupportedEncodingException;

@WebServlet("/admin/book/*")
@MultipartConfig(fileSizeThreshold = 1024 * 1024 * 2, // 2MB
                 maxFileSize = 1024 * 1024 * 10, // 10MB
                 maxRequestSize = 1024 * 1024 * 50) // 50MB
public class BookManagementServlet extends HttpServlet {
    private Gson gson = new Gson();
    private static final String UPLOAD_BASE_DIR = "D:/library_images"; 

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        String pathInfo = request.getPathInfo();
        
        if (pathInfo == null || pathInfo.equals("/")) {
            // 获取所有图书
            getAllBooks(request, response);
        } else {
            // 获取单个图书
            String[] splits = pathInfo.split("/");
            if (splits.length == 2) {
                int bookId = Integer.parseInt(splits[1]);
                getBook(bookId, response);
            }
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        // 只处理新增图书
        String title = request.getParameter("title");
        String author = request.getParameter("author");
        String isbn = request.getParameter("isbn");
        String publisher = request.getParameter("publisher");
        String publishDate = request.getParameter("publish_date");
        String category = request.getParameter("category");
        int totalCopies = Integer.parseInt(request.getParameter("total_copies"));

        Part imagePart = request.getPart("image");
        String imagePath = null;
        if (imagePart != null && imagePart.getSize() > 0) {
            imagePath = uploadFile(imagePart, request);
        }
        addBook(title, author, isbn, publisher, publishDate, category, totalCopies, imagePath, request, response);
    }

    @Override
    protected void doPut(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        // 更新图书或批准图书
        String pathInfo = request.getPathInfo();
        String[] splits = pathInfo.split("/");
        
        if (splits.length == 3 && "approve".equals(splits[2])) { // /admin/book/{bookId}/approve
            int bookId = Integer.parseInt(splits[1]);
            approveBook(bookId, response);
        } else if (splits.length == 2) { // /admin/book/{bookId} for update
            int bookId = Integer.parseInt(splits[1]);
            
            String title = request.getParameter("title");
            String author = request.getParameter("author");
            String isbn = request.getParameter("isbn");
            String publisher = request.getParameter("publisher");
            String publishDate = request.getParameter("publish_date");
            String category = request.getParameter("category");
            int totalCopies = Integer.parseInt(request.getParameter("total_copies"));

            Part imagePart = request.getPart("image");
            String imagePath = null;
            boolean keepExistingImage = "true".equals(request.getParameter("keep_existing_image"));

            if (imagePart != null && imagePart.getSize() > 0) {
                imagePath = uploadFile(imagePart, request);
            } else if (keepExistingImage) {
                // If no new image is uploaded and client requests to keep existing, pass null to updateBook
                // updateBook will then know not to change the image_path
                imagePath = null; 
            } else {
                // If no new image and not explicitly keeping existing, this implies clearing the image if needed.
                // For now, we will handle this in updateBook: if imagePath is null and not keeping, it will set to null.
                imagePath = null;
            }
            updateBook(bookId, title, author, isbn, publisher, publishDate, category, totalCopies, imagePath, keepExistingImage, response);
        } else {
            response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            JSONObject jsonResponse = new JSONObject();
            jsonResponse.put("success", false);
            jsonResponse.put("message", "无效的请求路径");
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            response.getWriter().write(jsonResponse.toString());
        }
    }

    @Override
    protected void doDelete(HttpServletRequest request, HttpServletResponse response) 
            throws ServletException, IOException {
        // 下架图书
        String pathInfo = request.getPathInfo();
        String[] splits = pathInfo.split("/");
        if (splits.length == 2) {
            int bookId = Integer.parseInt(splits[1]);
            removeBook(bookId, response);
        }
    }

    private void getAllBooks(HttpServletRequest request, HttpServletResponse response) 
            throws IOException {
        String searchTerm = request.getParameter("q");
        String sql = "SELECT * FROM books ";
        boolean hasWhereClause = false;

        if (searchTerm != null && !searchTerm.trim().isEmpty()) {
            sql += "WHERE (title LIKE ? OR author LIKE ? OR isbn LIKE ? OR publisher LIKE ? OR category LIKE ?)";
            hasWhereClause = true;
        }

        if (hasWhereClause) {
            sql += " AND status IN ('active', 'pending_review') ORDER BY create_time DESC";
        } else {
            sql += " WHERE status IN ('active', 'pending_review') ORDER BY create_time DESC";
        }

        try (Connection conn = DBUtil.getConnection()) {
            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                if (searchTerm != null && !searchTerm.trim().isEmpty()) {
                    for (int i = 1; i <= 5; i++) {
                        pstmt.setString(i, "%" + searchTerm + "%");
                    }
                }

                try (ResultSet rs = pstmt.executeQuery()) {
                
                List<JSONObject> books = new ArrayList<>();
                while (rs.next()) {
                    JSONObject book = new JSONObject();
                    book.put("id", rs.getInt("id"));
                    book.put("title", rs.getString("title"));
                    book.put("author", rs.getString("author"));
                    book.put("isbn", rs.getString("isbn"));
                    book.put("publisher", rs.getString("publisher"));
                    book.put("publish_date", rs.getString("publish_date"));
                    book.put("category", rs.getString("category"));
                    book.put("total_copies", rs.getInt("total_copies"));
                    book.put("available_copies", rs.getInt("available_copies"));
                    book.put("image_path", rs.getString("image_path")); // 获取图片路径
                    book.put("status", rs.getString("status"));
                    books.add(book);
                }
                
                response.setContentType("application/json");
                response.setCharacterEncoding("UTF-8");
                response.getWriter().write(books.toString());
            }
        }
        } catch (SQLException e) {
            e.printStackTrace();
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

    private void getBook(int bookId, HttpServletResponse response) throws IOException {
        try (Connection conn = DBUtil.getConnection()) {
            String sql = "SELECT * FROM books WHERE id = ?";
            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setInt(1, bookId);
                
                try (ResultSet rs = pstmt.executeQuery()) {
                    if (rs.next()) {
                        JSONObject book = new JSONObject();
                        book.put("id", rs.getInt("id"));
                        book.put("title", rs.getString("title"));
                        book.put("author", rs.getString("author"));
                        book.put("isbn", rs.getString("isbn"));
                        book.put("publisher", rs.getString("publisher"));
                        book.put("publish_date", rs.getString("publish_date"));
                        book.put("category", rs.getString("category"));
                        book.put("total_copies", rs.getInt("total_copies"));
                        book.put("available_copies", rs.getInt("available_copies"));
                        book.put("image_path", rs.getString("image_path")); // 获取图片路径
                        book.put("status", rs.getString("status"));
                        
                        response.setContentType("application/json");
                        response.setCharacterEncoding("UTF-8");
                        response.getWriter().write(book.toString());
                    } else {
                        response.setStatus(HttpServletResponse.SC_NOT_FOUND);
                    }
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

    private void addBook(String title, String author, String isbn, String publisher, 
                           String publishDate, String category, int totalCopies, String imagePath, 
                           HttpServletRequest request, HttpServletResponse response) throws IOException {
        System.err.println("DEBUG: Entering addBook method.");
        JSONObject jsonResponse = new JSONObject();
        HttpSession session = request.getSession(false);
        if (session == null || session.getAttribute("userId") == null) {
            System.err.println("DEBUG: Session is null or userId is null. Returning 401.");
            jsonResponse.put("success", false);
            jsonResponse.put("message", "用户未登录，请重新登录。");
            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // 401 Unauthorized
            response.setContentType("application/json");
            response.setCharacterEncoding("UTF-8");
            response.getWriter().write(jsonResponse.toString());
            return;
        }
        int uploaderId = (int) session.getAttribute("userId");
        System.err.println("DEBUG: uploaderId = " + uploaderId);
        try (Connection conn = DBUtil.getConnection()) {
            String sql = "INSERT INTO books (title, author, isbn, publisher, publish_date, category, total_copies, available_copies, image_path, status, uploader_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setString(1, title);
                pstmt.setString(2, author);
                pstmt.setString(3, isbn);
                pstmt.setString(4, publisher);
                pstmt.setString(5, publishDate);
                pstmt.setString(6, category);
                pstmt.setInt(7, totalCopies);
                pstmt.setInt(8, totalCopies); // 新增时可用数量等于总数量
                pstmt.setString(9, imagePath);
                pstmt.setString(10, "pending_review"); // 默认设置为待审核
                pstmt.setInt(11, uploaderId); // 设置上传者ID
                int result = pstmt.executeUpdate();
                if (result > 0) {
                    jsonResponse.put("success", true);
                    jsonResponse.put("message", "图书添加成功，待审核");
                } else {
                    jsonResponse.put("success", false);
                    jsonResponse.put("message", "添加图书失败");
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
            jsonResponse.put("success", false);
            jsonResponse.put("message", "数据库操作失败: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            jsonResponse.put("success", false);
            jsonResponse.put("message", "系统错误: " + e.getMessage());
        }
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(jsonResponse.toString());
    }

    private void updateBook(int bookId, String title, String author, String isbn, String publisher, 
                            String publishDate, String category, int totalCopies, String imagePath, 
                            boolean keepExistingImage, HttpServletResponse response) throws IOException {
        System.out.println("updateBook: Starting update for bookId: " + bookId);
        System.out.println("updateBook: Parameters received: ");
        System.out.println("Title: " + title);
        System.out.println("Author: " + author);
        System.out.println("ISBN: " + isbn);
        System.out.println("Publisher: " + publisher);
        System.out.println("Publish Date: " + publishDate);
        System.out.println("Category: " + category);
        System.out.println("Total Copies: " + totalCopies);
        System.out.println("Image Path: " + imagePath);
        
        JSONObject jsonResponse = new JSONObject();
        try (Connection conn = DBUtil.getConnection()) {
            String sql = "UPDATE books SET title=?, author=?, isbn=?, publisher=?, publish_date=?, category=?, total_copies=?, available_copies=?";
            if (imagePath != null) {
                sql += ", image_path=?";
            } else if (!keepExistingImage) { // If not keeping existing and imagePath is null, it means clear it.
                sql += ", image_path=NULL";
            }
            
            sql += " WHERE id=?";

            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                int i = 1;
                pstmt.setString(i++, title);
                pstmt.setString(i++, author);
                pstmt.setString(i++, isbn);
                pstmt.setString(i++, publisher);
                pstmt.setString(i++, publishDate);
                pstmt.setString(i++, category);
                pstmt.setInt(i++, totalCopies);
                pstmt.setInt(i++, totalCopies); // 更新时可用数量等于总数量
                
                if (imagePath != null) {
                    pstmt.setString(i++, imagePath);
                }
                // No else if (!keepExistingImage) here, as that's handled by the SQL string directly setting to NULL

                pstmt.setInt(i++, bookId);

                int result = pstmt.executeUpdate();
                if (result > 0) {
                    jsonResponse.put("success", true);
                    jsonResponse.put("message", "图书信息更新成功");
                } else {
                    jsonResponse.put("success", false);
                    jsonResponse.put("message", "更新图书信息失败");
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
            jsonResponse.put("success", false);
            jsonResponse.put("message", "数据库操作失败: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            jsonResponse.put("success", false);
            jsonResponse.put("message", "系统错误: " + e.getMessage());
        }
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(jsonResponse.toString());
    }

    private void approveBook(int bookId, HttpServletResponse response) throws IOException {
        JSONObject jsonResponse = new JSONObject();
        try (Connection conn = DBUtil.getConnection()) {
            String sql = "UPDATE books SET status = 'active' WHERE id = ?";
            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setInt(1, bookId);
                int result = pstmt.executeUpdate();
                if (result > 0) {
                    jsonResponse.put("success", true);
                    jsonResponse.put("message", "图书批准上架成功");
                } else {
                    jsonResponse.put("success", false);
                    jsonResponse.put("message", "批准上架失败");
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
            jsonResponse.put("success", false);
            jsonResponse.put("message", "数据库操作失败: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            jsonResponse.put("success", false);
            jsonResponse.put("message", "系统错误: " + e.getMessage());
        }
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(jsonResponse.toString());
    }

    private void removeBook(int bookId, HttpServletResponse response) throws IOException {
        JSONObject jsonResponse = new JSONObject();
        try (Connection conn = DBUtil.getConnection()) {
            String sql = "UPDATE books SET status = 'removed' WHERE id = ?";
            try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
                pstmt.setInt(1, bookId);
                int result = pstmt.executeUpdate();
                if (result > 0) {
                    jsonResponse.put("success", true);
                    jsonResponse.put("message", "图书已下架");
                } else {
                    jsonResponse.put("success", false);
                    jsonResponse.put("message", "下架失败");
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
            jsonResponse.put("success", false);
            jsonResponse.put("message", "数据库操作失败: " + e.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
            jsonResponse.put("success", false);
            jsonResponse.put("message", "系统错误: " + e.getMessage());
        }
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(jsonResponse.toString());
    }

    private String uploadFile(Part filePart, HttpServletRequest request) throws IOException {
        String fileName = UUID.randomUUID().toString() + "_" + Paths.get(filePart.getSubmittedFileName()).getFileName().toString();
        Path uploadPath = Paths.get(UPLOAD_BASE_DIR);
        if (!Files.exists(uploadPath)) {
            Files.createDirectories(uploadPath);
        }
        Path filePath = uploadPath.resolve(fileName);
        try (InputStream input = filePart.getInputStream()) {
            Files.copy(input, filePath, java.nio.file.StandardCopyOption.REPLACE_EXISTING);
        }
        return fileName;
    }
} 